import sys
from paste.request import parse_formvars
import paste.exceptions.formatter
from webob import Request
import md5
from e3.core.db import *
from e3.core.tpl import Tpl
from e3.utils import inifile
import json

class MainApp(object):
    def __init__(self):
        self.environ = None
        self._config = None
        self.parsed_url = []
        self.menu = []
        self.menu_id_path = []
        self.current_menu = []
        self.menu_props = []
        self.current_module = None
        self.user = {}
        self.tpl_vars = []
        self.real_url = ""
        self.rights = []
        self.db = None
    
    def __call__(self, environ, start_response):
#        self.db.query("SELECT * FROM `t1`")
#        row = self.db.get_row()
#        result = []
#        for k, v in row.iteritems():
#            result.append(v)
        try:
            self.config(environ)
        except:
            start_response('500 Internal Server Error', [('content-type', 'text/plain')], )
            output = 'Error reading configuration'
            return [output]
        
        try:   
            self.db = Db()
            mcd = self._config.data["mysql"]
            self.db.connect(mcd["host"], mcd["user"], mcd["pass"], mcd["name"])
        except DbError as e:
            start_response('500 Internal Server Error', [('content-type', 'text/plain')], )
            output = e.value   #error.error_message
            return [output]
        
        try:
            self.tpl = Tpl()
            self.tpl.set_tpldir(self.site_root + "/templates/")
        except:
            start_response('500 Internal Server Error', [('content-type', 'text/plain')], )
            output = 'Error creating template'
            return [output]
        
        try:    
            self.parseUrl()
        except Exception as e:
            type, value, traceback = sys.exc_info()
            output = repr(type) + repr(value) + repr(traceback) + e.value
            start_response('500 Internal Server Error', [('content-type', 'text/plain')], )
            return [output]
        
        self.capture_props()
        self.run_modules()
                     
        start_response('200 OK', [('content-type', 'text/html')], )
        output = self.tpl.out()
        return [output]

   
    def auth(self):
        pass
    
    def is_auth(self, uids, force = False):
        if self.user.__len__() == 0:
            return False
        if uids.count(self.user['id']) > 0:
            return True
        elif force:
            self.login()
            return False
    
    def login(self):
        pass
    
    def config(self, environ):
        self.environ = environ 
        self.request = Request(self.environ)
        self.site_root = self.environ['DOCUMENT_ROOT']
        self.script_name = self.environ['SCRIPT_FILENAME']
        self._config = inifile.IniFile(self.site_root+"/config/config.ini")
        sys.path.append(self.site_root + "/site_modules/")
    
    def parseUrl(self):
        self.real_url = self.request.path
        self.parsed_url = self.real_url.split("/")
        self.parsed_url[0] = "/"
        if self.parsed_url[1] == "":
            self.parsed_url.pop(1)
        
        sql = """SELECT `t2`.`in_menu`, `t2`.`id`, `t2`.`name`, count(`t1`.`id`) as `level`, 
                      REPLACE(GROUP_CONCAT(`t1`.`url` ORDER by `t1`.`lft` SEPARATOR '/'), '//','/') as `full_path` 
                      FROM `menu` as `t1`, `menu` as `t2` 
                      WHERE `t2`.`lft` BETWEEN `t1`.`lft` and `t1`.`rgt` 
                      GROUP BY `t2`.`id` 
                      ORDER BY `t2`.`lft`"""
        self.db.query(sql)
        self.menu = self.db.get_all(keyField = "full_path")
        
        url = ""
        self.menu_id_path = []
        self.menu_id_path.append(self.menu['/']['id'])
        for node in self.parsed_url:
            if node == "/":
                continue
            if (self.menu.has_key(url + "/" + node)):
                url = url + "/" + node
                self.menu_id_path.append(self.menu[url]['id'])
            else:
                break
        return
    
    def capture_props(self):
        currentId = self.menu_id_path.pop()
        sql = "SELECT p.* FROM props AS p INNER JOIN menu_props as mp ON mp.prop_id = p.id INNER JOIN menu as m ON mp.menu_id = m.id WHERE m.id = "+currentId+" ORDER BY mp.order ASC;"
        self.menu_id_path.append(currentId)

        self.db.query(sql)
        self.menu_props = self.db.get_all()
        for row in self.menu_props:
            if row['type'] == '_template':
                self.process_template(row['value'])
            if row['type'] == '_rights':
                self.process_rights(row['value'])
#            if row['type'] == '_module':
#                self.process_module(row['value'])
#            if row['type'] == '_text':
#                self.process_text(row['value'])
        return
    
    def process_template(self, value):
        tmp = json.loads(value, "utf-8")
        self.tpl.set_tpl(tmp['path'])
        self.tpl.add_data("_tpl", tmp)
     
    def process_rights(self, value):
        self.rights = json.loads(value, "utf-8")
    
    def run_modules(self):
        for property in self.menu_props:
            if property['type'] == "_module":
                self.current_module = json.loads(property['value'], "utf-8") 
                import_instr = "from " + self.current_module['package'] + " import " + self.current_module['class']
                create_instr = "mod = " + self.current_module['class'] + "(self)"
                execute_instr = "mod()"
                exec import_instr
                exec create_instr
                exec execute_instr
            elif property['type'] == "_text":
                pass